package cc.iotkit.plugins.tcp.parser;

import cc.iotkit.plugins.tcp.bean.DataUp;
import cc.iotkit.plugins.tcp.bean.Payload;
import cc.iotkit.plugins.tcp.bean.ReportedData;
import cc.iotkit.plugins.tcp.enums.DeviceType;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import lombok.extern.slf4j.Slf4j;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

import static cc.iotkit.plugins.tcp.enums.CommandType.*;


/**
 * 数据解码
 *
 * @author sjg
 */
@Slf4j
public class EdgeComputingDataDecoder {

    public static EdgeComputingDataPackage decode(Buffer buffer) {
        EdgeComputingDataPackage data = new EdgeComputingDataPackage();
        String asciiString = buffer.toString(StandardCharsets.US_ASCII);
        asciiString+="}]}]}";
        JsonObject json = new JsonObject(asciiString);
        // 获取 JSON 中的相关字段
        short type = json.getInteger("type").shortValue();
        data.setCode(type);
        if(type == CODE_DATA_UP.getCode()){
            List<DataUp> reportData = new ArrayList<>();
            JsonArray extensionDetails = json.getJsonArray("extensionDetails");
            for (int j = 0; j < extensionDetails.size(); j++) {
                JsonObject extensionDetail = extensionDetails.getJsonObject(j);
                DataUp dataUp = new DataUp();
                dataUp.setId(extensionDetail.getString("id"));
                dataUp.setCode(extensionDetail.getInteger("code"));
                JsonArray reportedDatas = extensionDetail.getJsonArray("data");
                List<ReportedData> rds = new ArrayList<>();
                float E=0;
                float Pt=0;
                float UrAt=0;
                float IrAt=0;
                // 处理 property
                for (int i = 0; i < reportedDatas.size(); i++) {
                    JsonObject jsonObject = reportedDatas.getJsonObject(i);
                    ReportedData reportedData = new ReportedData();

                    //如果是电表数据，需要做二次计算调整
                    if (DeviceType.ELECTRIC_METER.getCode()==dataUp.getCode()){
                        if ("eKey".equals(jsonObject.getString("n"))){
                            E = jsonObject.getFloat("v");
                        }else if ("uratKey".equals(jsonObject.getString("n"))){
                            UrAt = jsonObject.getFloat("v");
                        }else if ("iratKey".equals(jsonObject.getString("n"))){
                            IrAt = jsonObject.getFloat("v");
                        }else if ("ptKey".equals(jsonObject.getString("n"))){
                            Pt = jsonObject.getFloat("v");
                        }
                        if (jsonObject.getString("v")==null
                                || (jsonObject.getString("v")!=null && jsonObject.getString("v").indexOf("occurred")>-1)){
                            jsonObject.put("v","0.0");
                        }
                    }

                    String v = jsonObject.getString("v");
                    reportedData.setName(jsonObject.getString("n"));
                    reportedData.setValue(v);
                    rds.add(reportedData);
                }

                //电表，计算电能、功率、电流
                if (DeviceType.ELECTRIC_METER.getCode()==dataUp.getCode()){
                    //电压：不用做调整
                    //电能：用ImpEp*IrAt

                    float electricEnergy = E*IrAt;
                    ReportedData reportedData = new ReportedData();
                    reportedData.setName("electricEnergy");
                    reportedData.setValue(electricEnergy+"");
                    rds.add(reportedData);
                    //有功功率 P = Px(x=t、a、b、c)×(UrAt×0.1)×IrAt×0.1
                    float power = Pt*IrAt;
                    reportedData = new ReportedData();
                    reportedData.setName("power");
                    reportedData.setValue(power+"");
                    rds.add(reportedData);

                    reportedData = new ReportedData();
                    reportedData.setName("urat");
                    reportedData.setValue(UrAt+"");
                    rds.add(reportedData);

                    reportedData = new ReportedData();
                    reportedData.setName("irat");
                    reportedData.setValue(IrAt+"");
                    rds.add(reportedData);

                    reportedData = new ReportedData();
                    reportedData.setName("impep");
                    reportedData.setValue(E+"");
                    rds.add(reportedData);
                }

                //重新计算电流 electricity_a、electricity_b、electricity_c * IrAt
                //电流：要用采集的值*IrAt    electricity_a、b、c *IrAt
                if (DeviceType.ELECTRIC_METER.getCode() == dataUp.getCode()) {
                    for (int i = 0; i < rds.size(); i++) {
                        ReportedData reportedData = rds.get(i);
                        if (reportedData.getValue()!=null) {
                            String v = reportedData.getValue();
                            if ("electricity_a".equals(reportedData.getName()) && v != null) {
                                reportedData.setValue((Float.parseFloat(v) * IrAt) + "");
                            } else if ("electricity_b".equals(reportedData.getName()) && v != null) {
                                reportedData.setValue((Float.parseFloat(v) * IrAt) + "");
                            } else if ("electricity_c".equals(reportedData.getName()) && v != null) {
                                reportedData.setValue((Float.parseFloat(v) * IrAt) + "");
                            }
                        }
                    }
                }
                dataUp.setData(rds);
                reportData.add(dataUp);
            }
            Payload payload = new Payload();
            payload.setDeviceDataList(reportData);
            data.setPayload(payload);
        }
        if (type == CODE_REGISTER.getCode()) {
            return data;
        }
        if (type == CODE_HEARTBEAT.getCode()) {
            return data;
        }
        return data;
    }

}
